package dev;

/**
 * TODO:
	 * handler implementeren voor resterende argumenten die niet expliciet gebonden zijn: handler kan in geval van Cimple dan id bijvoegen voor server requests
	 * omvormen tot StateArgs: arguments worden gebonden aan een state en worden zodoende (in)actief in de adresbalk
 * @author Cref
 */
import dev.EventScope;

using hxtc.use.ForString;
using hxtc.web.Data;
using ES5;

class WebsiteArgs implements Dynamic<Property<String>> {
	var hash:Hash<Property<String>>;
	var evt:EventScope;
	var locationUpdater: Binder;
	function resolve(key:String) {
		if (!hash.exists(key)) {
			var p = new Property();
			locationUpdater.bind(p.change);
			hash.set(key, p);
		}
		return hash.get(key);
	}
	public function new(w:Window) {
		win = w;
		hash = new Hash();
		evt = EventScope.global;//TODO: EventScope.forWindow(w);
		locationUpdater = evt.updater(updateLocation);
		var t = this;
		w.addEventListener('popstate', function(e) {
			t.updateProperties(t.getCurrentLocation().before('?',true),t.getCurrentArgs());
		}, false);
	}
	function updateLocation() {
		var args:Dynamic<String> = getCurrentArgs();
		for (key in hash.keys()) args.set(key, hash.get(key).value);
		var d = args.document;
		args.document.delete();
		var qs = args.serialize();
		if (qs.length > 0) qs = '?' + qs;
		var url = d + qs;
		if (url != getCurrentLocation()) {
			win.history.pushState(null, win.document.title, win.document.baseURI + url + win.location.hash);
			//updateProperties();
		}
	}
	public function loadURL(url:String) {
		updateProperties(url.before('?',true),url.after('?').unserialize());
	}
	function updateProperties(doc:String,args:Dynamic<String>) {
		for (key in hash.keys()) hash.get(key).value = args.get(key);
		resolve('document').value = doc;
	}
	function getCurrentLocation() {
		return win.location.href.after(win.document.baseURI).before('#',true);
	}
	function getCurrentArgs():Dynamic<String> {
		return win.location.search.after('?').unserialize();
	}
	var win:Window;
}